use std::cell::RefCell;
use std::rc::{Rc, Weak};
use crate::List::{Cons, Nil};

///  弱引用Weak<T>
/// 特点：
/// - 弱引用通过RC::downgrade传递Rc实例的引用，调用Rc::downgrade会得到Weak<T>类型的智能指针，同时将weak_count加1（不是将strong_count加1）
/// - 区别在于weak_count无需计数未0就能使Rc实例被清理，只要strong_count为0就可以了
/// - 可以通过RC::upgrade方法返回Option<Rc<T>>对象

enum List {
    Cons(i32, RefCell<Weak<List>>),
    Nil,
}

impl List {
    fn tail(&self) -> Option<RefCell<Weak<List>>> {
        match self {
            Cons(_, item) => Some(item.clone()),
            Nil => None,
        }
    }
}

fn main() {
    let a = Rc::new(Cons(5, RefCell::new(Weak::new())));
    println!("1 a initial rc count = {}, weak count = {}", Rc::strong_count(&a), Rc::weak_count(&a));
    println!("1 a next item = {:?}", a.tail());

    let b = Rc::new(Cons(10, RefCell::new(Weak::new())));

    if let Some(link) = b.tail() {
        *link.borrow_mut() = Rc::downgrade(&a);
    }
    println!("2 a initial rc count = {}, weak count = {}", Rc::strong_count(&a), Rc::weak_count(&a));
    println!("2 b initial rc count = {}, weak count = {}", Rc::strong_count(&b), Rc::weak_count(&b));
    println!("2 b next item = {:?}", b.tail());

    if let Some(link) = a.tail() {
        *link.borrow_mut() = Rc::downgrade(&b);
    }
    println!("3 a initial rc count = {}, weak count = {}", Rc::strong_count(&a), Rc::weak_count(&a));
    println!("3 b initial rc count = {}, weak count = {}", Rc::strong_count(&b), Rc::weak_count(&b));
    println!("3 a next item = {:?}", a.tail());

    println!("Hello, world!");
}
